﻿<template>
    <div class="pdf-box" @click="stopDrop">
        <div class="pdf-header">
            <pdf-header :pageInfo="pageInfo" @onDownload="onDownload" @pageChange="pageChange" />
        </div>

        <div class="pdf-content">
            <!-- 组件区域 -->
            <div class="comlist-view" v-show="false">
                <comlist-view />
            </div>

            <!-- 中间画布区域 -->
            <div class="canvas-view">
                <!-- 下层pdf预览 -->
                <div class="pdf-canvas" :style="{ width: pdfStyle.with, height: pdfStyle.height }">
                    <pdf-preview
                        :url="pdfUrl"
                        v-if="pdfUrl"
                        @initPdfPage="initPdfPage"
                        @pdfContainerSize="pdfContainerSize"
                        :pageNum="pageInfo.current"
                    />
                </div>

                <!-- 上层的dom操作 -->
                <div
                    class="dom-view"
                    :style="{ width: pdfStyle.width, height: pdfStyle.height }"
                    @dragover.prevent
                    @drop="handleDrop"
                    ref="domViewRef"
                >
                    <draggable-view
                        v-for="(item, index) in list"
                        :key="index"
                        :schema="item"
                        @moveComponent="moveComponent"
                        @updateText="updateText"
                        @click.native="showAttr(item)"
                        @changeStyle="changeStyle"
                        @startDrop="startDrop"
                    />
                </div>
            </div>

            <!-- 属性区域 -->
            <div class="attr-view" v-show="false">
                <attr-view v-if="attrConfig" :schema="attrConfig" @removeAttr="removeAttr" @updateAttr="updateText" />
                <div v-else>暂无属性数据</div>
            </div>
        </div>
    </div>
</template>

<script setup>
import { computed, onMounted, provide, ref } from 'vue';
import AttrView from '@/components/attr-view/attr-view.vue';
import PdfHeader from '@/components/pdf-header/pdf-header.vue';
import ComlistView from '@/components/comlist-view/comlist-view.vue';
import DraggableView from '@/components/draggable-view/draggable-view.vue';
import PdfPreview from '@/components/pdf-preview/pdf-preview.vue';
import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';
import { v4 as uuidv4 } from 'uuid';
import { usePdfStore } from '@/stores/usePdfStore';
const pdfStore = usePdfStore();
// https://esign-webapi.smartapp.net.cn/esign/complatepdf/2025/06/17/d67aefbc41f3454c91f6f93e51f04838.pdf
const pdfUrl = ref('/test1.pdf');

// pdf分页
const pageInfo = ref({
    current: 1,
    total: 0,
});

const initPdfPage = val => {
    pageInfo.value = val;
};

const pageChange = num => {
    pageInfo.value.current = num;
};

// 获取加载pdf的尺寸信息
const pdfStyle = ref({
    width: '300px',
    height: '100%',
});

const pdfContainerSize = val => {
    pdfStyle.value.width = val.width;
    pdfStyle.value.height = val.height;
    const rect = domViewRef.value.getBoundingClientRect();
    pdfStore.setPdfViewRect(rect);

    // console.log(pdfStyle.value, '2');
};

// 下载
const onDownload = async () => {
    const pdfPath = '/test1.pdf';
    const response = await fetch(pdfPath);
    const pdfBytes = await response.arrayBuffer();

    // 定义要添加的文本注释（示例数据）
    // const annotations = [
    //     { page: 1, x: pdfStore.pdfList[0].x / 1.5, y: (pdfStore.pdfList[0].y + 40) / 1.5, text: pdfStore.pdfList[0].val, fontSize: 12 },
    //     // { page: 1, x: 200, y: 100, text: 'world', fontSize: 14 },
    // ];

    const annotations = mergePdf(pdfStore.pdfList);
    // 添加文本到 PDF

    const modifiedPdfBytes = await addTextToPdf(pdfBytes, annotations);

    // 创建下载链接
    const blob = new Blob([modifiedPdfBytes], { type: 'application/pdf' });
    const url = URL.createObjectURL(blob);

    const a = document.createElement('a');
    a.href = url;
    a.download = 'modified.pdf';
    a.click();

    // 释放 URL 对象
    URL.revokeObjectURL(url);
};

function mergePdf(list) {
    return list.map(item => {
        return {
            ...item,
            x: parseInt(item.x / pdfStore.scale),
            y: parseInt((item.y + item.height) / pdfStore.scale),
            text: item.val,
        };
    });
}

// 在指定坐标添加文本并保存新 PDF
async function addTextToPdf(pdfBytes, annotations) {
    // 加载原始 PDF
    const pdfDoc = await PDFDocument.load(pdfBytes);

    // 加载字体
    const font = await pdfDoc.embedFont(StandardFonts.Helvetica);

    // 处理每一页
    for (let i = 0; i < pdfDoc.getPageCount(); i++) {
        const page = pdfDoc.getPage(i);
        const { width, height } = page.getSize();

        // 获取当前页的所有注释
        const pageAnnotations = annotations.filter(anno => anno.page === i + 1);

        // 在页面上绘制文本
        pageAnnotations.forEach(anno => {
            // 注意：pdf-lib 的坐标系原点在左下角，而 PDF.js 在左上角
            const y = height - anno.y; // 转换 Y 坐标

            page.drawText(anno.text, {
                x: anno.x,
                y: y,
                size: anno.fontSize,
                font: font,
                color: anno.color || rgb(0, 0, 0), // 默认黑色
            });
        });
    }

    // 保存修改后的 PDF
    const modifiedPdfBytes = await pdfDoc.save();
    return modifiedPdfBytes;
}

// 进入目标区域停止
const domViewRef = ref(null);
const handleDrop = async e => {
    const canvasBoxRect = domViewRef.value.getBoundingClientRect();
    // 传递的对象
    const componentObj = JSON.parse(e.dataTransfer.getData('key'));

    // 获取 组件相对于画布的坐标 （鼠标的位置x - 画布的x - 鼠标在组件中的x）
    const x = e.clientX - canvasBoxRect.left - componentObj.x;
    const y = e.clientY - canvasBoxRect.top - componentObj.y;

    //  添加新的文本框
    let item = {
        id: uuidv4(),
        x,
        y,
        comType: componentObj.comType,
        val: componentObj.val,
        page: pageInfo.value.current,
        width: 100,
        height: 30,
        fontSize: 12,
        isActive: false,
    };
    // 存入本地中
    getAttrConfig(item);
    pdfStore.addPdfList(item);

    console.log(pdfStore.pdfList, 'list');
};

// 计算属性，计算当前页的拖拽列表
const list = computed(() => {
    return pdfStore.pdfList.filter(item => item.page === pageInfo.value.current);
});

// 组件移动
const moveComponent = val => {
    const idx = pdfStore.pdfList.findIndex(item => item.id === val.id);
    if (idx === -1) return;

    if (val.x <= 0) {
        return;
    }

    if (val.x + val.width >= parseInt(pdfStyle.value.width)) {
        return;
    }

    if (val.y <= 0) {
        return;
    }

    if (val.y + val.height >= parseInt(pdfStyle.value.height)) {
        return;
    }

    pdfStore.pdfList[idx].x = val.x;
    pdfStore.pdfList[idx].y = val.y;
    pdfStore.updatePdfList();
};

// 属性控制
const attrConfig = ref(null);
function getAttrConfig(val) {
    attrConfig.value = val;
}
const showAttr = item => {
    getAttrConfig(item);
};

const removeAttr = id => {
    pdfStore.removePdfList(id);
    attrConfig.value = null;
};

const changeStyle = val => {
    const idx = pdfStore.pdfList.findIndex(item => item.id === val.id);
    if (idx === -1) return;

    const item = pdfStore.pdfList[idx];

    if (val.width + item.x >= parseInt(pdfStyle.value.width)) {
        return;
    }

    pdfStore.pdfList[idx].width = val.width;
    pdfStore.pdfList[idx].height = val.height;
    pdfStore.updatePdfList();
};

// 文本更新
const updateText = val => {
    const idx = pdfStore.pdfList.findIndex(item => item.id === val.id);
    if (idx === -1) return;
    pdfStore.pdfList[idx].val = val.val;
    pdfStore.updatePdfList();
};

// 特殊处理
const stopDrop = () => {
    attrConfig.value = null;
    pdfStore.pdfList.forEach(item => (item.isActive = false));
};
const startDrop = id => {
    pdfStore.pdfList.forEach(item => (item.isActive = false));
    const idx = pdfStore.pdfList.findIndex(item => item.id === id);
    pdfStore.pdfList[idx].isActive = true;
};

onMounted(() => {
    pdfStore.pdfList = pdfStore.pdfList;
});
</script>

<style scoped lang="scss">
.pdf-box {
    height: 100%;
    width: 100%;
    overflow-x: hidden;
    .pdf-header {
        height: 70px;
        border-bottom: 1px solid #eee;
    }
    .pdf-content {
        height: calc(100% - 70px);
        display: flex;
        .comlist-view {
            width: 300px;
            height: 100%;
            padding: 20px;
            display: flex;
            flex-direction: column;
        }
        .canvas-view {
            position: relative;
            flex: 1;
            border-left: 1px solid #eee;
            border-right: 1px solid #eee;
            overflow-y: auto;
            overflow-x: hidden;
            .pdf-canvas {
                position: absolute;
                // border: 1px solid red;
                left: 50%;
                top: 0;
                transform: translateX(-50%);
                z-index: 1;
            }
            .dom-view {
                position: absolute;
                box-shadow: -1px 3px 5px rgba(0, 0, 0, 0.3);
                left: 50%;
                top: 0;
                transform: translateX(-50%);
                z-index: 2;
            }
        }
        .attr-view {
            width: 300px;
            height: 100%;
            padding: 20px;
        }
    }
}
</style>
